import type { Plugin, PluginOption, ProxyOptions } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { pathResolve } from './vite.config'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
import OptimizationPersist from 'vite-plugin-optimize-persist'
import PkgConfig from 'vite-plugin-package-config'
import legacy from '@vitejs/plugin-legacy'
import babel from 'vite-plugin-babel'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'

type ProxyTargetList = Record<string, ProxyOptions & { rewrite: (path: string) => string }>

const httpsRE = /^https:\/\//
export const createVitePlugin = () => {
  const vitePlugins: (Plugin | Plugin[] | PluginOption[])[] = [
    vue(),
    vueJsx(),
    // 按需导入 naive
    AutoImport({
      // 自动导入 Vue 相关函数，如：ref, reactive, toRef 等
      imports: ['vue'],

      resolvers: [
        // 自动导入 naive-ui 组件
        NaiveUiResolver()
      ],
      dts: './auto-imports.d.ts',
      // Generate corresponding .eslintrc-auto-import.json file.
      // eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals
      eslintrc: {
        enabled: false, // Default `false`
        filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
        globalsPropValue: true // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
      }
    }),
    Components({
      resolvers: [NaiveUiResolver()]
      // dts: './components.d.ts',
    }),
    // 启用时间优化 我们第一次使用按需引入后，它就会在 package.json 中生成内容（生成的内容根据你项目所使用的组件而定），下次进来就可以快速的跑起项目啦
    // PkgConfig(),
    // OptimizationPersist(),
    // 为打包后的文件提供传统浏览器兼容性支持。
    legacy({
      targets: ['defaults', 'not IE 11']
    }),
    // Babel will try to pick up Babel config files (.babelrc or .babelrc.json)
    babel(),
    createSvgIconsPlugin({
      // 指定需要缓存的图标文件夹
      iconDirs: [pathResolve('src/assets/icons')],
      // 指定symbolId格式
      symbolId: 'icon-[dir]-[name]'

      /**
       * 自定义插入位置
       * @default: body-last
       */
      // inject?: 'body-last' | 'body-first'

      /**
       * custom dom id
       * @default: __svg__icons__dom__
       */
      // customDomId: '__svg__icons__dom__',
    })
  ]
  return vitePlugins
}

/**
 * 创建dev运行跨越
 * @param list
 */
export const createViteProxy = (
  list: [string, string][] = []
): Record<string, string | ProxyOptions> => {
  const ret: ProxyTargetList = {}
  if (typeof list === 'object' && list instanceof Array) {
    for (const [prefix, target] of list) {
      const isHttps = httpsRE.test(target)
      // https://github.com/http-party/node-http-proxy#options
      ret[prefix] = {
        target: target,
        changeOrigin: true,
        ws: true,
        rewrite: (path: string) => path.replace(new RegExp(`^${prefix}`), ''),
        // 将真实代理地址放到请求头
        bypass: (req, res, options: any) => {
          /**
           * @description URL(url,base)是一个表示绝对或者相对URL的DOMString
           * @description 如果url是相对URL,则会将base作为基准URL
           * @description 如果url是绝对URL,则无论参数base是否存在，都将被忽略
           */
          const proxyUrl =
            new URL(options?.rewrite(req?.url) || '', options.target as string)?.href || ''
          console.log('proxyUrl', proxyUrl)
          req.headers['x-req-proxyUrl'] = proxyUrl //设置请求头无效
          res.setHeader('x-req-proxyUrl', proxyUrl) //设置响应头有效
        },
        // https is require secure=false
        ...(isHttps ? { secure: false } : {})
      }
    }
  } else {
    console.log('跨域运行出错！')
  }
  return ret
}

/**
 * @description: 处理env文件（将所有环境变量配置文件读取到 process.env）
 * @param envConf
 */
export const wrapperEnv = (envConf: Recordable): ViteEnv => {
  const ret: any = {}

  for (const envName of Object.keys(envConf)) {
    let realName = envConf[envName].replace(/\\n/g, '\n')
    realName = realName === 'true' ? true : realName === 'false' ? false : realName

    if (envName === 'VITE_APP_PORT') {
      realName = Number(realName)
    }
    if (envName === 'VITE_APP_PROXY') {
      try {
        realName = JSON.parse(realName)
      } catch (error) {
        /* empty */
        console.log('VITE_PROXY报错')
      }
    }
    ret[envName] = realName
    process.env[envName] = realName
  }
  return ret
}
